package minidb.parse;
import java.lang.System;
import java.util.*;


%%

%implements Lexer
%function nextToken
%type java_cup.runtime.Symbol
%char
%line
%public

%{
private int pos_inline;
private int post_yychar=-1;
private String new_text="";



private java_cup.runtime.Symbol ReturnToken(int symType, Object value) 
{
    return new java_cup.runtime.Symbol(symType, yychar, yychar+yylength(), value);
}

private void PrintError(String msg)
{
	//pos_inline=yychar-post_yychar;
	//System.err.println("error@"+yyline+"."+pos_inline+":"+ msg);
}
private void Print(String msg)
{
	//System.out.print(msg);
}


%}

%eofval{

 	if(yy_lexical_state==STRING)
	{
      	PrintError("string unclosed!");
     }
      
	 return ReturnToken(sym.EOF,null);
	 
%eofval}    


ALPHA=[A-Za-z]
DIGIT=[0-9]
ID={ALPHA}({ALPHA}|_|{DIGIT})*
NEW_LINE=(\r\n|\n|\r|\f)
NON_NEW_LINE=[\ \t]
DOUBLE={DIGIT}+\.{DIGIT}+


%state STRING

%%
<YYINITIAL>","  	{Print("COMMA ");return ReturnToken(sym.COMMA,null);}
<YYINITIAL>":"  	{Print("COLON ");return ReturnToken(sym.COLON,null);}
<YYINITIAL>";"  	{Print("SEMICOLON ");return ReturnToken(sym.SEMICOLON,null);}
<YYINITIAL>"("  	{Print("LPAR ");return ReturnToken(sym.LPAR,null);}
<YYINITIAL>")"  	{Print("RPAR ");return ReturnToken(sym.RPAR,null);}
<YYINITIAL>"["  	{Print("LBRACK ");return ReturnToken(sym.LBRACK,null);}
<YYINITIAL>"]"  	{Print("RBRACK ");return ReturnToken(sym.RBRACK,null);}
<YYINITIAL>"{"  	{Print("LBRACE ");return ReturnToken(sym.LBRACE,null);}
<YYINITIAL>"}"  	{Print("RBRACE ");return ReturnToken(sym.RBRACE,null);}
<YYINITIAL>"."  	{Print("DOT ");return ReturnToken(sym.DOT,null);}
<YYINITIAL>"+"  	{Print("PLUS ");return ReturnToken(sym.PLUS,null);}
<YYINITIAL>"-"  	{Print("MINUS ");return ReturnToken(sym.MINUS,null);}
<YYINITIAL>"*"  	{Print("TIMES ");return ReturnToken(sym.TIMES,null);}
<YYINITIAL>"/"  	{Print("DIVIDE ");return ReturnToken(sym.DIVIDE,null);}
<YYINITIAL>"="  	{Print("EQ ");return ReturnToken(sym.EQ,null);}
<YYINITIAL>"<>"  	{Print("NEQ ");return ReturnToken(sym.NEQ,null);}
<YYINITIAL>"<"  	{Print("LT ");return ReturnToken(sym.LT,null);}
<YYINITIAL>"<="  	{Print("LE ");return ReturnToken(sym.LE,null);}
<YYINITIAL>">"  	{Print("GT ");return ReturnToken(sym.GT,null);}
<YYINITIAL>">="  	{Print("GE ");return ReturnToken(sym.GE,null);}
<YYINITIAL>"and"  	{Print("AND ");return ReturnToken(sym.AND,null);}
<YYINITIAL>"or"  	{Print("OR ");return ReturnToken(sym.OR,null);}
<YYINITIAL>"not"  	{Print("NOT ");return ReturnToken(sym.NOT,null);}
<YYINITIAL>"is"  	{Print("IS ");return ReturnToken(sym.IS,null);}
<YYINITIAL>"null"  	{Print("NULL ");return ReturnToken(sym.NULL,null);}
<YYINITIAL>"#"  	{Print("SHARP ");return ReturnToken(sym.SHARP,null);}


<YYINITIAL>"create"  	{Print("CREATE ");return ReturnToken(sym.CREATE,null);}
<YYINITIAL>"table"  	{Print("TABLE ");return ReturnToken(sym.TABLE,null);}
<YYINITIAL>"primary"  	{Print("PRIMARY ");return ReturnToken(sym.PRIMARY,null);}
<YYINITIAL>"key"  		{Print("KEY ");return ReturnToken(sym.KEY,null);}
<YYINITIAL>"integer"  	{Print("INTEGER ");return ReturnToken(sym.INTEGER,null);}
<YYINITIAL>"double"  	{Print("DOUBLE ");return ReturnToken(sym.DOUBLE,null);}
<YYINITIAL>"char"  		{Print("CHAR ");return ReturnToken(sym.CHAR,null);}
<YYINITIAL>"varchar"  	{Print("VARCHAR ");return ReturnToken(sym.VARCHAR,null);}
<YYINITIAL>"select "  	{Print("SELECT ");return ReturnToken(sym.SELECT,null);}
<YYINITIAL>"from"  		{Print("FROM ");return ReturnToken(sym.FROM,null);}
<YYINITIAL>"where"  	{Print("WHERE ");return ReturnToken(sym.WHERE,null);}
<YYINITIAL>"insert"  	{Print("INSERT ");return ReturnToken(sym.INSERT,null);}
<YYINITIAL>"into"  		{Print("INTO ");return ReturnToken(sym.INTO,null);}
<YYINITIAL>"values"  	{Print("VALUES ");return ReturnToken(sym.VALUES,null);}
<YYINITIAL>"update"  	{Print("UPDATE ");return ReturnToken(sym.UPDATE,null);}
<YYINITIAL>"set"	  	{Print("SET ");return ReturnToken(sym.SET,null);}
<YYINITIAL>"delete"		{Print("DELETE ");return ReturnToken(sym.DELETE,null);}

<YYINITIAL>"join"	  	{Print("JOIN ");return ReturnToken(sym.JOIN,null);}
<YYINITIAL>"inner"	  	{Print("INNER ");return ReturnToken(sym.INNER,null);}
<YYINITIAL>"outer"	  	{Print("OUTER ");return ReturnToken(sym.OUTER,null);}
<YYINITIAL>"natural"	{Print("NATURAL ");return ReturnToken(sym.NATURAL,null);}
<YYINITIAL>"left"	  	{Print("LEFT ");return ReturnToken(sym.LEFT,null);}
<YYINITIAL>"right"	  	{Print("RIGHT ");return ReturnToken(sym.RIGHT,null);}
<YYINITIAL>"full"	  	{Print("FULL ");return ReturnToken(sym.FULL,null);}
<YYINITIAL>"on"	  		{Print("ON ");return ReturnToken(sym.ON,null);}

<YYINITIAL>"sum"	  	{Print("SUM ");return ReturnToken(sym.SUM,null);}
<YYINITIAL>"avg"	  	{Print("AVG ");return ReturnToken(sym.AVG,null);}
<YYINITIAL>"count"	  	{Print("COUNT ");return ReturnToken(sym.COUNT,null);}
<YYINITIAL>"min"	  	{Print("MIN ");return ReturnToken(sym.MIN,null);}
<YYINITIAL>"max"	  	{Print("MAX ");return ReturnToken(sym.MAX,null);}
<YYINITIAL>"group"	  	{Print("GROUP ");return ReturnToken(sym.GROUP,null);}
<YYINITIAL>"by"	  		{Print("BY ");return ReturnToken(sym.BY,null);}
<YYINITIAL>"having"		{Print("HAVING ");return ReturnToken(sym.HAVING,null);}

<YYINITIAL>"view"	  	{Print("VIEW ");return ReturnToken(sym.VIEW,null);}
<YYINITIAL>"as "	  	{Print("AS ");return ReturnToken(sym.AS,null);}
<YYINITIAL>"index"	  	{Print("INDEX ");return ReturnToken(sym.INDEX,null);}
<YYINITIAL>"drop"	  	{Print("DROP ");return ReturnToken(sym.DROP,null);}

<YYINITIAL>"like"	  	{Print("LIKE ");return ReturnToken(sym.LIKE,null);}

<YYINITIAL>"order"	  	{Print("ORDER ");return ReturnToken(sym.ORDER,null);}
<YYINITIAL>"asc"	  	{Print("ASC ");return ReturnToken(sym.ASC,null);}
<YYINITIAL>"desc"	  	{Print("DESC ");return ReturnToken(sym.DESC,null);}

<YYINITIAL>"start"	  	{Print("START ");return ReturnToken(sym.START,null);}
<YYINITIAL>"transaction" {Print("TRANSACTION ");return ReturnToken(sym.TRANSACTION,null);}
<YYINITIAL>"commit"	  	{Print("COMMIT ");return ReturnToken(sym.COMMIT,null);}

<YYINITIAL>"user"	  	{Print("USER ");return ReturnToken(sym.USER,null);}
<YYINITIAL>"add"	  	{Print("ADD ");return ReturnToken(sym.ADD,null);}

<YYINITIAL>"check"	  	{Print("CHECK ");return ReturnToken(sym.CHECK,null);}


<YYINITIAL>{ID} 			{Print("ID ");return ReturnToken(sym.ID,yytext());}
<YYINITIAL>{DIGIT}+  		{Print("INT ");return ReturnToken(sym.INT,new Integer(yytext()));}
<YYINITIAL>-{DIGIT}+  		{Print("UINT ");return ReturnToken(sym.INT,new Integer(yytext()));}
<YYINITIAL>{DOUBLE}  		{Print("DOUBLE ");return ReturnToken(sym.DBL,new Double(yytext()));}
<YYINITIAL>-{DOUBLE}  		{Print("UDOUBLE ");return ReturnToken(sym.DBL,new Double(yytext()));}

<YYINITIAL>{NON_NEW_LINE} 	{}
<YYINITIAL>{NEW_LINE} 		{Print("\r\n");post_yychar=yychar;}

<YYINITIAL> \'				{yybegin(STRING);new_text="";}

<STRING> {NON_NEW_LINE}*	{new_text+=(yytext());}

<STRING> \\(r|n|t|\'|\\)
{
	if(yytext().equals("\\t"))
		new_text+='\t';
	else if(yytext().equals("\\n"))
		new_text+='\n';
	else if(yytext().equals("\\r"))
		new_text+='\r';
	else if(yytext().equals("\\\'"))
		new_text+='\'';
	else if(yytext().equals("\\\\"))
		new_text+='\\';
	
}

<STRING> \\{DIGIT}{DIGIT}{DIGIT}  
{
	int temp_int=Integer.parseInt(yytext().substring(1,4));
	if(temp_int>255)
	{
	    yybegin(YYINITIAL);
	    PrintError("\""+yytext()+"\" exceeded limitation!");
	}
	else
		new_text+=((char)(temp_int));
}

<STRING> {NEW_LINE}		{Print("\r\n");yybegin(YYINITIAL);PrintError("string unclosed!");}	

<STRING> ";"	{yybegin(YYINITIAL);PrintError("\";\" is not allowed in a string");}

<STRING> \\.    {yybegin(YYINITIAL);PrintError("undefinded escape sequence \""+yytext()+"...\"");}

<STRING> \'		{yybegin(YYINITIAL);Print("STRING ");return ReturnToken(sym.STRING,new_text);}	
				
<STRING> .  	{new_text+=(yytext());}



<YYINITIAL> . 		{PrintError("undefined symbol \""+yytext()+"...\"");}



